package com.jdd.modules.sdk.utils;

import com.jdd.common.util.WeekType;
import lombok.extern.slf4j.Slf4j;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author ：jdd孙庆伟
 * @date ：Created in 2021/9/13 9:18
 * @description：菲利德控制板
 * @modified By：`
 * @version: 1.0
 */
@Slf4j
public class FeiLiDeLedUtils {
    private static final SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /*** 功能描述: 校准控制板显示时间为当前时间
     * @Author: lcy
     * @Date: 2022/1/4
     */
    public static byte[] calibrationTime(){
        //获取当前本地时间
        String now = simpleDateFormat.format(new Date());
        //分割成2020-08-24与10:10:52
        String[] oneSplit = now.split(" ");
        //将2020-08-24分割三部分
        String[] front = oneSplit[0].split("-");
        //split[0] 年
        //split[1] 月
        //split[2] 日
        //将10:10:52分割三部分
        String[] back = oneSplit[1].split(":");
        //split1[0] 时
        //split1[1] 分
        //split1[2] 秒
        //固定字段
        StringBuilder builder = new StringBuilder();
        builder.append("00" + "64" + "FF" + "FF" + "05"+"08");
        builder.append(bytes2HexString(Int2Bytes_LE(Integer.parseInt(front[0]))), 0, 4);
        builder.append(hex10To16(Integer.parseInt(front[1])));
        builder.append(hex10To16(Integer.parseInt(front[2])));
        Calendar calendar = Calendar.getInstance();
        //一周第一天是否为星期天
        boolean isFirstSunday = (calendar.getFirstDayOfWeek() == Calendar.SUNDAY);
        //获取周几
        int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
        //若一周第一天为星期天，则-1
        if(isFirstSunday){
            weekDay = weekDay - 1;
            if(weekDay == 0){
                weekDay = 7;
            }
        }
        builder.append("0").append(WeekType.getLedNumByWeekNum(weekDay));
        builder.append(hex10To16(Integer.parseInt(back[0])));
        builder.append(hex10To16(Integer.parseInt(back[1])));
        builder.append(hex10To16(Integer.parseInt(back[2])));
        String crc16 = getCRC16(hexToByteArray(builder.toString()));
        builder.append(crc16);
        log.info("同步时间的数据处理前:" + builder);
        return hexToByteArray(builder.toString());
    }

    /**
     * 菲利德控制板LED显示
     *
     * @param str
     * @param like
     * @return byte[]
     * @author jdd孙庆伟
     * @date 2021/9/13 09:25:30
     * @version 1.0
     */
    public static byte[] ledTemporaryDisplay(String str, String like) throws Exception {
        byte[] gbkStr = str.getBytes("GBK");
        String TL = byteToHex(gbkStr.length);

        String DL = Integer.toHexString(gbkStr.length + 19);
        String testPrefix = "00" + "64" + "FF" + "FF" + "62" + DL + like + "000000000000" + TL + "00";
        String formatted = bytes2HexString(gbkStr);
        String aaa = testPrefix + formatted;
        String crc = getCRC16(hexToByteArray(aaa));
        String ss = aaa + crc;

        log.info("String:" + str + "内容:" + ss);
        return hexToByteArray(ss);
    }

    public static byte[] ledDownloadText(String str, String like) throws Exception {
        byte[] gbkStr = str.getBytes("GBK");
        String TL = byteToHex(gbkStr.length);

        String DL = Integer.toHexString(gbkStr.length + 20);
        String testPrefix = "00" + "64" + "FF" + "FF" + "67" + DL + like + "000000000000" + TL + "00";
        String formatted = bytes2HexString(gbkStr);
        String aaa = testPrefix + formatted;
        String crc = getCRC16(hexToByteArray(aaa));
        String ss = aaa + crc;

        log.info("String:" + str + "内容:" + ss);
        return hexToByteArray(ss);
    }

    /**
     * 菲利德控制板 语言播报
     *
     * @param str
     * @return byte[]
     * @author jdd孙庆伟
     * @date 2021/9/13 09:26:04
     * @version 1.0
     */
    public static byte[] sdKUnkledSpeech(String str) throws Exception {
        byte[] gb2312s = str.getBytes("GB2312");
        int strLengths = gb2312s.length + 1;
        String lhex = Integer.toHexString(strLengths);
        String s = "00" + "64" + "FF" + "FF" + "30" + lhex + "01";
        byte[] bytes = str.getBytes("GBK");
        String formatted = bytes2HexString(bytes);
        String aaa = s + formatted;
        String crc = getCRC16(hexToByteArray(aaa));
        String ss = s + formatted + crc;
        return hexToByteArray(ss);
    }

    /*** 功能描述: 16进制转10进制
     * @param num 需要转的16进制
     * @Author: lcy
     * @Date: 2022/1/4
     */
    public static String hex16To10(String num){
        if (num == null) {
            throw new NullPointerException();
        }
        BigInteger bigInteger = new BigInteger(num, 16);
        return bigInteger.toString();
    }

    /**
     * 计算CRC16校验码
     *
     * @param bytes
     * @return
     */
    public static String getCRC16(byte[] bytes) {
        int CRC = 0x0000ffff;
        int POLYNOMIAL = 0x0000a001;

        int i, j;
        for (i = 0; i < bytes.length; i++) {
            CRC ^= ((int) bytes[i] & 0x000000ff);
            for (j = 0; j < 8; j++) {
                if ((CRC & 0x00000001) != 0) {
                    CRC >>= 1;
                    CRC ^= POLYNOMIAL;
                } else {
                    CRC >>= 1;
                }
            }
        }
        String result = Integer.toHexString(CRC).toUpperCase();
        if (result.length() != 4) {
            StringBuffer sb = new StringBuffer("0000");
            result = sb.replace(4 - result.length(), 4, result).toString();
        }
        //交换高低位
        return result.substring(2, 4) + result.substring(0, 2);
    }

    /**
     * 输入数字转成小端模式
     *
     * @param iValue
     * @return
     */
    public static byte[] Int2Bytes_LE(int iValue) {
        byte[] rst = new byte[4];
        // 先写int的最后一个字节
        rst[0] = (byte) (iValue & 0xFF);
        // int 倒数第二个字节
        rst[1] = (byte) ((iValue & 0xFF00) >> 8);
        // int 倒数第三个字节
        rst[2] = (byte) ((iValue & 0xFF0000) >> 16);
        // int 第一个字节
        rst[3] = (byte) ((iValue & 0xFF000000) >> 24);
        return rst;
    }
    /**
     * byte数组转16进制字节字符串
     *
     * @param data
     * @return
     */
    public static String bytes2HexString(byte[] data) {
        if (data == null) {
            throw new NullPointerException();
        }

        StringBuilder buffer = new StringBuilder();
        for (byte b : data) {
            String hex = Integer.toHexString(b & 0xff);
            if (hex.length() == 1) {
                buffer.append('0');
            }
            buffer.append(hex);
        }
        return buffer.toString().toUpperCase();
    }

    /**
     * 将一个整形化为十六进制，并以字符串的形式返回
     */
    private final static String[] hexArray = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    public static String byteToHex(int n) {
        if (n < 0) {
            n = n + 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexArray[d1] + hexArray[d2];
    }

    /**
     * hex字符串转byte数组
     *
     * @param inHex 待转换的Hex字符串
     * @return 转换后的byte数组结果
     */
    public static byte[] hexToByteArray(String inHex) {
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1) {
            //奇数
            hexlen++;
            result = new byte[(hexlen / 2)];
            inHex = "0" + inHex;
        } else {
            //偶数
            result = new byte[(hexlen / 2)];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = hexToByte(inHex.substring(i, i + 2));
            j++;
        }
        return result;
    }

    public static String hex10To16(int valueTen){
        return String.format("%08X",valueTen).substring(6,8);
    }
    /**
     * Hex字符串转byte
     *
     * @param inHex 待转换的Hex字符串
     * @return 转换后的byte
     */
    public static byte hexToByte(String inHex) {
        return (byte) Integer.parseInt(inHex, 16);
    }
}
